#include "ThreadPool.h"

#include "MessageQueue.h"
#include "SessionHandler.h"

#include <iostream>

#include "Logger.h"

// the constructor just launches some amount of workers
ThreadPool::ThreadPool(size_t threads)
	: stop(false)
{
	for (size_t i = 0; i < threads; ++i)
		workers.emplace_back(
			[this]
	{
		for (;;)
		{
            //std::cout << std::this_thread::get_id() << std::endl;
			LOGINFO(std::string("ThreadPool::ThreadPool - 1"));
			{
				std::unique_lock<std::mutex> lock(this->queue_mutex);
				this->condition.wait(lock,
					[this] { return this->stop || !CMessageQueue::getInstance()->empty(); });
				if (this->stop && CMessageQueue::getInstance()->empty())
					return;
			}

            CMessage message;
			message = CMessageQueue::getInstance()->getMessage();

			CSessionHandler handler;
			handler.handleSession(message);
		}
	}
	);
}

// the destructor joins all threads
ThreadPool::~ThreadPool()
{
    //std::cout << "ThreadPool::~ThreadPool" << std::endl;
	LOGDEBUG("ThreadPool Destructor");
	{
		std::unique_lock<std::mutex> lock(queue_mutex);
		stop = true;
	}
	condition.notify_all();
	for (std::thread &worker : workers)
		worker.join();
}

